home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
404_02
/
Discussion
< prev
next >
Wrap
Internet Message Format
|
1993-07-17
|
9KB
From coetmeur Mon Jul 19 14:08:43 1993
To: ramanand@thor.ece.uc.EDU
Subject: Re: flex++/bison++
Content-Type: X-sun-attachment
Content-Length: 8382
X-Lines: 312
Status: RO
----------
X-Sun-Data-Type: text
X-Sun-Data-Description: text
X-Sun-Data-Name: text
X-Sun-Content-Lines: 114
> From root Thu Jul 15 20:00:27 1993
> >From ramanand@thor.ece.uc.EDU Thu Jul 15 20:00:27 1993
> Date: 15 Jul 93 13:57:27-0400
> From: John Holmes Sr <ramanand@thor.ece.uc.EDU>
> Subject: flex++/bison++
> To: coetmeur@icdc.fr
> MIME-version: 1.0
> Content-Type> : > text/plain> ; > charset=US-ASCII>
> Content-transfer-encoding: 7bit
>
> Hello Alain,
>
> I recently ported the flex++/bison++ software that you have put up on the
> ftp server under comp.compilers.
>
> First of all I would like to complement you on a job well underakten. The
> documentation is quite beneficial.
>
> However I have been having some problems with generating multiple parsers
> in the same executable. It is quite possible that my understanding of the
> full capabilities of the notions of class etc. are not quite up to the
> mark. I would appreciate any help you can provide.
>
>
> I have tried the following approach. If there is a better way, please let
> me know.
>
>
> Prepare two bison++ files. Each of them declares a different class
> for the parser. Each of them declares its LEX_BODY as = 0 (i.e. a
> pure virtual function). Prepare two flex++ files. Each of them
> inherits the properties of the corresponding parser class and defines
> the lexical analyser functions.
>
> So I now have two sets of header files.
>
> a. parser1.h and lex1.h
> b. parser2.h and lex2.h
>
>
>
>
> Each set of parser/lexical analyser individually compiles correctly
> with the latest gnu c++ compiler. However, if I try to include both
> the lexical header files (lex1.c and lex2.c) in the main file, I get syntax
> errors. The reason is in the first two lines of these header files. They
> are duplicated here below:
>
> #ifndef FLEX_HEADER_lex__h
> #define FLEX_HEADER_lex__h
> ...
> ...
>
>
> Since both these files define the same symbol FLEX_HEADER_lex__h,
> obviously the second time that I include the header file, it is ignored
> by the preprocessor.
>
> Can you give me some solutions to this. Either I could somehow rename this
> symbol , or you have a better class hierarchy that I am unaware of
> currently.
>
The way we can use multiple parser or scanner is by changing
the name of the scanner/parser with the directive %name. it is
ESSENTIAL. By default and for compatibility the name is set to 'lex'
and 'parse', but it should be changed to a different name for each
parser/scanner. Further, the scanner and parser must not have the
same name. the name given is used as the class name, and to build
many symbol names. So you should give a %name directive, before any
other in the flex++ and bison++ files. If all the header use the
symbol FLEX_HEADER_lex__h if shoul mean that they use the same
%name. If it is not the case, it is a very important bug. I was not
able to reproduce it with the data I have.
The way to comunicate between the scanner and the parser is not
a trivial choic, and at our site we discussed much about it. The
problems are complex since the scanner use parser constant for token
ID, the parser use the scanner function as token furnisher, and so
on...
The way that we used is to create a derived class from the
parser class, containing the scanner itself, and redefining the
token reader function of the parser to call the scanner function of
the scanner. It seems good for many reasons:
- the compiler (ie parser+scanner) IS essentially a PARSER,
that USE a particular SCANNER to give tokens.
- the intermediate function that give tokens from the
scanner to the parser is a good place to put trace, and
management function (line count...)
The design was so important to explain to new users in our
site, that I decided to build a template of compiler that is a
base to modify. It should be present in misc++, but I send it as
attachment (4 files).
I am concient that the documentation I have given is very
technical, and assume a deep knowledge of flex, bison, C/C++, and
some design experiences.
Please tell me was is the result of your new try, successful or not.
Hoping I could help you, Best regard.
Alain Coetmeur
----------
X-Sun-Data-Type: rdti-source-makefile
X-Sun-Data-Name: makefile
X-Sun-Content-Lines: 28
.SUFFIXES : .cc .y .l $(SUFFIXES)
.cc.o :
CC -I$(CENTERCCLIBDIR)/incl -c $*.cc
.y.cc :
bison++ -d -o $*.cc -h $*.h $*.y
.l.cc :
flex++ -h$*.h -o$*.cc $*.l
.y.h :
bison++ -d -o $*.cc -h $*.h $*.y
.l.h :
flex++ -h$*.h -o$*.cc $*.l
all : compiler
MyCompiler.o : MyCompiler.cc MyParser.h MyScanner.h
MyParser.o : MyParser.cc MyParser.h
MyScanner.o : MyScanner.cc MyScanner.h MyParser.h
compiler : MyCompiler.o MyParser.o MyScanner.o
CC -o $@ MyCompiler.o MyParser.o MyScanner.o
----------
X-Sun-Data-Type: rdtq-source-l
X-Sun-Data-Name: MyScanner.l
X-Sun-Content-Lines: 42
/* %Z% %M% %Y% %Q% %I% %E% %U% (%F%) */
/*
* Nom du Fichier : |>nom_fichier<|
* Titre : |>Titre<|
* Auteur: |>auteur<|
* Date de creation : |>dateCreation<|
*/
/* Description :
* Document de reference : |>doc<|
* Objet : |>objet<|
*
*/
/*
* historique :
* |>date<| |>auteur<| |>objet<|
*/
/* -------------- declaration section -------------- */
%name MyScanner
%define LEX_PARAM YY_MyParser_STYPE *val,YY_MyParser_LTYPE *loc
%define MEMBERS public: int theLine,theColumn;
%define CONSTRUCTOR_INIT : theLine(1),theColumn(1)
%header{
#include "MyParser.h"
%}
%{
static char SccsId[]="%Z% %M% %Y% %Q% %I% %E% %U% (%F%)";
%}
/* -------------- rules section -------------- */
SPACES [ \t]+
%%
"\n" {val->ctype='\n';
theLine++;theColumn=1;
return MyParser::EOL_TOKEN; }
. {
val->ctype=yytext[0];
theColumn++;
return MyParser::CHAR_TOKEN; }
<<EOF>> { yyterminate();}
%%
----------
X-Sun-Data-Type: rdtq-source-y
X-Sun-Data-Name: MyParser.y
X-Sun-Content-Lines: 50
/* %Z% %M% %Y% %Q% %I% %E% %U% (%F%) */
/*
* Nom du Fichier : |>nom_fichier<|
* Titre : |>Titre<|
* Auteur: |>auteur<|
* Date de creation : |>dateCreation<|
*/
/* Description :
* Document de reference : |>doc<|
* Objet : |>objet<|
*
*/
/*
* historique :
* |>date<| |>auteur<| |>objet<|
*/
/* -------------- declaration section -------------- */
%name MyParser
%define LSP_NEEDED
%define ERROR_BODY =0
%define LEX_BODY =0
%header{
#include <stdio.h>
%}
%union {
int itype; /* for count */
char ctype; /* for char */
}
%token <ctype> EOL_TOKEN CHAR_TOKEN
%type <itype> file line lines chars
%start file
/* -------------- rules section -------------- */
/* Sample parser. Does count Chars in a line, and lines in file */
%%
file : lines
{printf("nlines=%d\n",$1); /* show line count */}
;
lines : line {$$=1; /* first line of all */}
| lines line {$$=$1+1; /* count one more line */}
;
line : chars EOL_TOKEN {$$=$1;printf("nchars=%d\n",$1); /* show char count */}
;
chars : CHAR_TOKEN { $$=1;/* first char of line */}
| chars CHAR_TOKEN {$$=$1+1; /* count one more char */}
;
%%
/* -------------- body section -------------- */
----------
X-Sun-Data-Type: rdtq-source-cc
X-Sun-Data-Name: MyCompiler.cc
X-Sun-Content-Lines: 52
static char SccsId[]="%Z% %M% %Y% %Q% %I% %E% %U% (%F%)";
//
// Nom du Fichier : |>nom_fichier<|
// Titre : |>Titre<|
// Auteur: |>auteur<|
// Date de creation : |>dateCreation<|
//
// Description :
// Document de reference : |>doc<|
// Objet : |>objet<|
//
//
//
// historique :
// |>date<| |>auteur<| |>objet<|
//
#include "MyScanner.h"
#include "MyParser.h"
class MyCompiler : public MyParser
{private:
MyScanner theScanner;
public:
virtual int yylex();
virtual void yyerror(char *m);
MyCompiler()
{};
};
int MyCompiler::yylex()
{
yylloc.first_line=theScanner.theLine;
yylloc.first_column=theScanner.theColumn;
int token=theScanner.yylex(&yylval,&yylloc);
yylloc.last_line=theScanner.theLine;
yylloc.la